﻿package com.zouloux.medias.sub 
{
	import com.zouloux.core.debug.Debug;
	import com.zouloux.medias.MediaEvent;
	import com.zouloux.medias.VideoController;
	import flash.display.Sprite;
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	/**
	 * ...
	 * @author ZoulouX
	 */
	public class SubTitleController extends EventDispatcher
	{
		/**
		 * Le controller de vidéo associé
		 */
		protected var _videoController			:VideoController;
		
		/**
		 * Le conteneur des sous-titres
		 */
		protected var _container				:Sprite 					= new Sprite();
		
		/**
		 * Le fichier XML de sous-titrage
		 */
		protected var _xml						:XML;
		
		/**
		 * L'ancien sous-titre
		 */
		protected var _oldSubTitle				:SubTitleItem;
		
		/**
		 * Largeur de la vidéo
		 */
		protected var _videoWidth				:Number						= 0;
		
		/**
		 * Hauteur de la vidéo
		 */
		protected var _videoHeight				:Number						= 0;
		
		/**
		 * Le fichier XML de sous-titrage
		 */
		public function get xml():XML { return _xml; }
		public function set xml(value:XML):void 
		{
			_xml = value;
		}
		
		/**
		 * Le conteneur des sous-titres
		 */
		public function get container():Sprite { return _container; }
		public function set container(value:Sprite):void 
		{
			_container = value;
		}
		
		/**
		 * Largeur de la vidéo associée
		 */
		public function get videoWidth():Number { return _videoWidth; }
		public function set videoWidth(value:Number):void 
		{
			_videoWidth = value;
		}
		
		/**
		 * Hauteur de la vidéo associée
		 */
		public function get videoHeight():Number { return _videoHeight; }
		public function set videoHeight(value:Number):void 
		{
			_videoHeight = value;
		}
		
		
		/**
		 * Le constructeur
		 */
		public function SubTitleController ()
		{
			
		}
		
		/**
		 * Connecter un controller vidéo
		 * @param	pVideoController : le controller de type VideoController
		 */
		public function connect (pVideoController:VideoController):void
		{
			// Enregistrer le controller vidéo
			_videoController = pVideoController;
			
			// Ecouter les cuePoints
			_videoController.addEventListener(MediaEvent.CUE_POINT, cuePointHandler);
			
			// Ecouter quand la vidéo est prête pour avoir les dimensions
			if (_videoController.ready)
				videoReadyHandler();
			else
				_videoController.addEventListener(MediaEvent.READY, videoReadyHandler);
		}
		
		/**
		 * Déconnecter le controller vidéo
		 */
		public function disconnect ():void
		{
			_videoController.removeEventListener(MediaEvent.CUE_POINT, cuePointHandler);
		}
		
		/**
		 * Récéption d'un cuePoint
		 * @param	event
		 */
		protected function cuePointHandler (event:MediaEvent):void
		{
			// Afficher par son ID
			showById(event.cuePointName);
		}
		
		/**
		 * La vidéo est prête
		 * @param	event
		 */
		protected function videoReadyHandler(event:MediaEvent = null):void 
		{
			Debug.core(this, "videoReadyHandler");
			
			// Associer les dimensions
			_videoWidth = _videoController.info.width;
			_videoHeight = _videoController.info.height;
		}
		
		/**
		 * Charger les sous-titres depuis un fichier XML
		 * @param	pUrl : URL du fichier XML
		 */
		public function loadSubtitles (pUrl:String):void
		{
			// Charger le fichier XML
			var loader:URLLoader = new URLLoader(new URLRequest(pUrl));
			
			// Ecouter
			loader.addEventListener(Event.COMPLETE, loadSubTitlesSuccess);
			loader.addEventListener(IOErrorEvent.IO_ERROR, loadSubTitlesError);
		}
		
		/**
		 * Le fichier est chargé
		 * @param	event
		 */
		protected function loadSubTitlesSuccess (event:Event):void
		{
			// Enregistrer l'xml
			_xml = new XML((event.target as URLLoader).data);
			
			// Redispatcher l'event
			dispatchEvent(new Event(Event.COMPLETE));
		}
		
		/**
		 * Le fichier n'a pas pu être chargé
		 * @param	event
		 */
		protected function loadSubTitlesError (event:IOErrorEvent):void
		{
			// Redispatcher l'event
			dispatchEvent(new IOErrorEvent(IOErrorEvent.IO_ERROR));
		}
		
		/**
		 * Afficher un sous titre par son ID
		 */
		public function showById (pId:String):void
		{
			// Vérifier si le fichier XML est chargé
			if (_xml != null)
			{
				// Récupérer le noeud
				var node:XMLList = _xml..cue.(@id == pId).sub as XMLList;
				
				// Vérifier si on a le noeud
				if (node != null)
				{
					// Parcourir tous les sous-titres pour ce temps
					for each (var item:XML in node as XMLList)
					{
						// Récupérer la valeur du texte
						var value:String = item.toString();
						
						// L'objet des paramètres
						var parameters:Object = { };
						
						// Parser les paramètres
						for each (var attribute:XML in item.attributes() as XMLList)
						{
							// Enregistrer ce paramètre
							parameters[attribute.name().toString().toLowerCase()] = attribute.toString();
						}
						
						// Afficher
						show(value, parameters);
					}
				}
			}
		}
		
		/**
		 * Afficher un sous titre
		 */
		public function show (pText:String, pParameters:Object = null):void
		{
			// Tuer l'ancien
			if (_oldSubTitle != null && _oldSubTitle.allowKill)
				_oldSubTitle.kill(true);
			
			// Créer le sousTitre
			_oldSubTitle = new SubTitleItem(pText, pParameters == null ? {} : pParameters, this);
			
			// Ajouter au container
			_container.addChild(_oldSubTitle);
		}
	}
}